package com.finalterm.gateway.config;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import com.alibaba.fastjson2.JSON;
import com.finalterm.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.ViewResolver;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;

/**
 * Sentinel网关配置
 * 配置自定义的限流响应处理
 */
@Slf4j
@Configuration
public class SentinelGatewayConfig {

    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public SentinelGatewayConfig(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    /**
     * 配置限流异常处理器
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    /**
     * 初始化限流响应处理
     */
    @PostConstruct
    public void initBlockRequestHandler() {
        BlockRequestHandler blockRequestHandler = (exchange, ex) -> {
            // 获取客户端IP（如果有的话）
            String clientIp = exchange.getAttribute("clientIp");
            if (clientIp == null) {
                clientIp = "unknown";
            }
            
            log.warn("IP {} 触发限流，请求路径: {}", clientIp, exchange.getRequest().getURI().getPath());
            
            // 构造限流响应
            Result<Object> result = Result.error(429, 
//                String.format("请求过于频繁，IP %s 已被限流，请稍后再试", clientIp));
                String.format("Too Many Requests", clientIp));

            return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                    .contentType(MediaType.APPLICATION_JSON)
                    .header("X-RateLimit-Limit", "50")
                    .header("X-RateLimit-Remaining", "0")
                    .header("X-RateLimit-Reset", String.valueOf(System.currentTimeMillis() / 1000 + 1))
                    .body(BodyInserters.fromValue(JSON.toJSONString(result)));
        };
        
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
        log.info("Sentinel网关限流响应处理器初始化完成");
    }
}
